#include "dbhelper.h"
#include <iostream>
#include <cstring>

using std::string;
using std::cerr;
using std::cout;
using std::endl;

// 构造函数：打开数据库连接
// 参数：dbname - 数据库文件名
dbHelper::dbHelper(const string& dbname) {
    // 尝试打开SQLite数据库
    if (sqlite3_open(dbname.data(), &db) != SQLITE_OK) {
        // 打开失败，输出错误信息
        cerr << "无法打开数据库: " << sqlite3_errmsg(db) << endl;
    } else {
        // 打开成功，输出成功信息
        cout << "成功打开数据库: " << dbname << endl;
    }
}

// 析构函数：关闭数据库连接
dbHelper::~dbHelper() {
    sqlite3_close(db);
}

// 用户注册功能
// 参数：name - 用户名，pswd - 密码
// 返回值：注册成功返回true，失败返回false
bool dbHelper::regist(const string& name, const string& pswd) {
    // SQL插入语句，使用参数占位符(?)
    const char* sql = "INSERT INTO user(name, pswd) VALUES(?, ?)";
    sqlite3_stmt* stmt = nullptr;
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备注册语句失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    // 绑定参数：用户名和密码
    sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, pswd.c_str(), -1, SQLITE_TRANSIENT);
    
    // 执行SQL语句
    int res = sqlite3_step(stmt);
    // 释放语句资源
    sqlite3_finalize(stmt);
    
    // 检查执行结果
    if (res != SQLITE_DONE) {
        cerr << "注册失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    cout << "用户注册成功: " << name << endl;
    return true;
}

// 用户登录功能
// 参数：name - 用户名，pswd - 密码
// 返回值：登录成功返回true，失败返回false
bool dbHelper::login(const string& name, const string& pswd) {
    // SQL查询语句，根据用户名查询密码
    const char* sql = "SELECT pswd FROM user WHERE name = ?";
    sqlite3_stmt* stmt = nullptr;
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备登录语句失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    // 绑定参数：用户名
    sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_TRANSIENT);
    
    // 执行SQL查询
    int res = sqlite3_step(stmt);
    if (res == SQLITE_ROW) {
        // 获取数据库中的密码
        const char* db_pswd = (const char*)sqlite3_column_text(stmt, 0);
        // 比较密码是否匹配
        bool success = (db_pswd != nullptr && pswd == db_pswd);
        // 释放语句资源
        sqlite3_finalize(stmt);
        
        cout << "登录尝试: " << name << " - " << (success ? "成功" : "失败") << endl;
        return success;
    }
    
    // 释放语句资源
    sqlite3_finalize(stmt);
    cerr << "用户不存在: " << name << endl;
    return false;
}

// 保存日程功能
// 参数：username - 用户名，date - 日期，event - 事件内容
// 返回值：保存成功返回true，失败返回false
bool dbHelper::saveSchedule(const string& username, const string& date, const string& event) {
    // SQL插入语句
    const char* sql = "INSERT INTO schedules(username, date, event) VALUES(?, ?, ?)";
    sqlite3_stmt* stmt = nullptr;
    
    cout << "尝试保存日程: " << username << ", " << date << ", " << event << endl;
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备保存日程语句失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    // 绑定参数：用户名、日期、事件内容
    sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, date.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 3, event.c_str(), -1, SQLITE_TRANSIENT);
    
    // 执行SQL语句
    int res = sqlite3_step(stmt);
    // 释放语句资源
    sqlite3_finalize(stmt);
    
    // 检查执行结果
    if (res != SQLITE_DONE) {
        cerr << "保存日程失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    cout << "日程保存成功" << endl;
    return true;
}

// 更新日程功能
// 参数：username - 用户名，oldDate - 原日期，newDate - 新日期，newEvent - 新事件内容
// 返回值：更新成功返回true，失败返回false
bool dbHelper::updateSchedule(const string& username, const string& oldDate, 
                            const string& newDate, const string& newEvent) {
    // SQL更新语句，根据用户名和原日期更新为新日期和新事件
    const char* sql = "UPDATE schedules SET date=?, event=? WHERE username=? AND date=?";
    sqlite3_stmt* stmt = nullptr;
    
    cout << "尝试更新日程: " << username << ", " << oldDate << " -> " << newDate << endl;
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备更新日程语句失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    // 绑定参数：新日期、新事件、用户名、原日期
    sqlite3_bind_text(stmt, 1, newDate.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, newEvent.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 3, username.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 4, oldDate.c_str(), -1, SQLITE_TRANSIENT);
    
    // 执行SQL语句
    int res = sqlite3_step(stmt);
    // 释放语句资源
    sqlite3_finalize(stmt);
    
    // 检查执行结果和影响的行数
    if (res != SQLITE_DONE || sqlite3_changes(db) == 0) {
        cerr << "更新日程失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    cout << "日程更新成功" << endl;
    return true;
}

// 删除日程功能
// 参数：username - 用户名，date - 日期
// 返回值：删除成功返回true，失败返回false
bool dbHelper::deleteSchedule(const string& username, const string& date) {
    // SQL删除语句，根据用户名和日期删除日程
    const char* sql = "DELETE FROM schedules WHERE username=? AND date=?";
    sqlite3_stmt* stmt = nullptr;
    
    cout << "尝试删除日程: " << username << ", " << date << endl;
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备删除日程语句失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    // 绑定参数：用户名、日期
    sqlite3_bind_text(stmt, 1, username.c_str(), -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, date.c_str(), -1, SQLITE_TRANSIENT);
    
    // 执行SQL语句
    int res = sqlite3_step(stmt);
    // 释放语句资源
    sqlite3_finalize(stmt);
    
    // 检查执行结果和影响的行数
    if (res != SQLITE_DONE || sqlite3_changes(db) == 0) {
        cerr << "删除日程失败: " << sqlite3_errmsg(db) << endl;
        return false;
    }
    
    cout << "日程删除成功" << endl;
    return true;
}

// 查询日程功能
// 参数：username - 用户名（实际未使用），date - 日期（可选，为空时查询所有日期）
// 返回值：包含日期和事件内容的键值对向量
std::vector<std::pair<std::string, std::string>> 
dbHelper::querySchedules(const std::string& username, const std::string& date) {
    // 存储查询结果的向量
    std::vector<std::pair<std::string, std::string>> result;
    sqlite3_stmt* stmt = nullptr;
    
    // 输出查询信息
    cout << "执行日程查询: ";
    if (!date.empty()) {
        cout << "date=" << date;
    }
    cout << endl;

    // 根据日期参数选择不同的SQL查询语句
    // 注意：此函数实际上忽略了username参数，查询所有用户的日程
    const char* sql = date.empty() ? 
        "SELECT date, event FROM schedules ORDER BY date" :  // 查询所有日期的所有日程
        "SELECT date, event FROM schedules WHERE date=?";    // 查询指定日期的所有日程
    
    // 准备SQL语句
    if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
        cerr << "准备查询语句失败: " << sqlite3_errmsg(db) << endl;
        return result;
    }
    
    // 只绑定日期参数（如果有），不再绑定用户名
    if (!date.empty()) {
        sqlite3_bind_text(stmt, 1, date.c_str(), -1, SQLITE_TRANSIENT);
    }
    
    // 遍历查询结果集
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        // 获取日期和事件内容
        const char* sdate = (const char*)sqlite3_column_text(stmt, 0);
        const char* event = (const char*)sqlite3_column_text(stmt, 1);
        
        // 确保数据不为空后添加到结果向量
        if (sdate && event) {
            result.emplace_back(sdate, event);
            cout << "查询到日程: " << sdate << " - " << event << endl;
        } else {
            cerr << "查询到空数据，跳过" << endl;
        }
    }
    
    // 释放语句资源
    sqlite3_finalize(stmt);
    
    // 输出查询结果统计
    if (result.empty()) {
        cout << "未查询到匹配的日程" << endl;
    } else {
        cout << "共查询到 " << result.size() << " 条日程" << endl;
    }
    
    return result;
}